// 函数在ts中的声明 ， 对于函数来说 我们一般会标识函数的本身类型，参数类型，返回值类型

// 函数关键字来声明
// function a(){} // function关键字声明的函数 无法在去给函数本身添加类型

// 表达式的方式来声明

// 如果你是直接赋值可以省略，如果你要限制sum的类型，在进行赋值， 那就需要写
type MySum = (a: number, b: number) => number;
let sum: MySum = (x: number, y: number): number => x + y;

// 这里调用时 是根据类型来做提示的
// sum(1,2);

// 函数依然支持可选参数 支持默认参数 和 省略运算符  ? 会被转换成联合运算符但是联合运算必须是必填的
function optionalArguments(x: string, y?: string, z?: string) {}
optionalArguments("a");

function defaultArguments(x: string = "", y: string) {
  // 因为x 可能不能传递 才会出现默认值，x就能是undefined
}
defaultArguments(undefined, "123");

function spreadAruments(...args: number[]) {
  // 因为x 可能不能传递 才会出现默认值，x就能是undefined
}
spreadAruments(1, 2, 3, 4);

function getVal(this: any, key: string) {
  // 可以在参数的第一个参数来表标明 this的类型
}
getVal.call({ abc: 123 }, "abc");

// 函数在ts中实现了函数的重载  一个函数可以实现多个功能 。

// 你给我一个字符串我就给你转化一个数组 'abc' => ['a','b','c']
// 给我个数字 12  => [1,2]

// 除了根据= 右边来推断，还会根据函数的返回值进行推断
function toArray(value: string): string[]; // 对string的情况进行了细化
function toArray(value: number): number[]; // 对number的情况进行了细化
function toArray(value: string | number) {
  // 这里是真实的实现
  if (typeof value === "string") {
    return value.split("");
  } else {
    return value.toString().split("").map(Number);
  }
}
// 根据参数或者返回值的不同的 实现了不同的功能
let r1 = toArray("abc");
let r2 = toArray(123);
export {};
